import json

from database.parkrecord import ParkRecordTable
from database.parktoken import ParkTokenTable
from models.account import Account

from typing import List
from models.query import ParkQuery, TaskQuery
from models.task import NewTaskModel, EditTaskModel, OperationTaskModel
from utils.logger import logger

import uvicorn
from uvicorn.config import LOGGING_CONFIG
from fastapi import FastAPI, Request, Response, HTTPException

import logging

import modules.access as access

from modules.access import accessToken

from models.exception import ParkAdminException

from starlette.middleware.cors import CORSMiddleware  #引入 CORS中间件模块
from starlette.responses import FileResponse
from fastapi.staticfiles import StaticFiles
from database.accesslog  import AccessLogTable
import modules.query as queryHandler
import modules.task as taskHandler
from models.parktoken import DbParkToken


import requests

app = FastAPI()

app.mount("/static", StaticFiles(directory="static"), name="static")

#设置允许访问的域名
origins = ["*"]  #也可以设置为"*"，即为所有。

#设置跨域传参
app.add_middleware(
    CORSMiddleware, 
    allow_origins=origins,  #设置允许的origins来源
    allow_credentials=True,
    allow_methods=["*"],  # 设置允许跨域的http方法，比如 get、post、put等。
    allow_headers=["*"])  #允许跨域的headers，可以用来鉴别来源等作用。


@app.get("/")
def parkadmin():
    return FileResponse('./index.html')

@app.get("/favicon.ico")
def parkadmin():
    return FileResponse('./favicon.ico')

@app.post("/api/parkadmin/user/login")
def parkadmin_user_login(account : Account):
    logger.info(f"login req: {account}")
    try:
        rsp = access.login(account)
    except ParkAdminException as e:
        rsp =  e.result()
    logger.info(f"login rsp: {rsp}")
    return rsp

@app.post("/api/parkadmin/user/logout")
def parkadmin_user_logout():
    try:
        return access.logout("")
    except ParkAdminException as e:
        return e.result()

@app.get("/api/parkadmin/user/info")
def parkadmin_user_info(token : str, request : Request):
    try:
        user = accessToken(request)
        with AccessLogTable() as db:
            db.insert(user.username, request.client.host)
            db.commit()
        return {"code": 20000, "data": user}
    except ParkAdminException as e:
        return e.result()

@app.get("/api/parkadmin/dashboard/one")
def parkadmin_dashboard_one(request : Request):
    try:
        accessToken(request)
        return {"code": 20000, "data": requests.get("https://api.xygeng.cn/one",verify=False).json()}
    except ParkAdminException as e:
        return e.result()

@app.post("/api/parkadmin/task/query")
def parkadmin_task_query(query : TaskQuery, request : Request):
    try:
        user = accessToken(request)
        return queryHandler.task(query, user)
    except ParkAdminException as e:
        return e.result()

@app.post("/api/parkadmin/taskrecord/query")
def parkadmin_taskrecord_query(query : TaskQuery, request : Request):
    try:
        user = accessToken(request)
        return queryHandler.taskrecord(query, user)
    except ParkAdminException as e:
        return e.result()
    
@app.post("/api/parkadmin/parkrecord/query")
def parkadmin_parkrecord_query(query : ParkQuery, request : Request):
    try:
        user = accessToken(request)
        return queryHandler.parkrecord(query, user)
    except ParkAdminException as e:
        return e.result()
    
@app.post("/api/parkadmin/task/new")
def parkadmin_task_new(model : NewTaskModel, request : Request):
    try:
        user = accessToken(request)
        return taskHandler.new_task(model, user)
    except ParkAdminException as e:
        return e.result()

@app.post("/api/parkadmin/task/edit")
def parkadmin_task_edit(model : EditTaskModel, request : Request):
    try:
        user = accessToken(request)
        return taskHandler.edit_task(model, user)
    except ParkAdminException as e:
        return e.result()

@app.post("/api/parkadmin/task/delete")
def parkadmin_task_delete(model: OperationTaskModel, request : Request):
    try:
        user = accessToken(request)
        return taskHandler.delete_task(model, user)
    except ParkAdminException as e:
        return e.result()
    
@app.post("/api/parkadmin/task/start")
def parkadmin_task_start(model: OperationTaskModel, request : Request):
    try:
        user = accessToken(request)
        return taskHandler.start_task(model, user)
    except ParkAdminException as e:
        return e.result()
    
@app.post("/api/parkadmin/task/stop")
def parkadmin_task_stop(model: OperationTaskModel, request : Request):
    try:
        user = accessToken(request)
        return taskHandler.stop_task(model, user)
    except ParkAdminException as e:
        return e.result()
    
@app.post("/api/parkadmin/taskrecord/polling")
def parkadmin_taskrecord_polling(total: int, query : TaskQuery, request : Request):
    try:
        user = accessToken(request)
        return taskHandler.polling_taskrecord(total, query, user)
    except ParkAdminException as e:
        return e.result()
    
@app.post("/api/parkadmin/parkrecord/polling")
def parkadmin_parkrecord_polling(total: int, query : ParkQuery, request : Request):
    try:
        user = accessToken(request)
        return taskHandler.polling_parkrecord(total, query, user)
    except ParkAdminException as e:
        return e.result()
    
@app.post("/api/parktoken/data")
def token_post(data: dict):
    token = DbParkToken().load(data)
    with ParkTokenTable() as db:
        index = db.insert(token)
        db.commit()
    logger.info(f"received token count: {len(data)}, return {index}")
    return {"code": 0, "data": index}


@app.post("/api/parktoken/data_list")
def token_post(data: List[dict]):
    with ParkTokenTable() as db:
        for item in data:
            index = db.insert(DbParkToken().load(item))
        db.commit()
    logger.info(f"received token count: {len(data)}, return {index}")
    return {"code": 0, "data": index}

if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=3652)
